package com.alibaba.citrus.cr.mn.order.center.facade.service.impl;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.enums.ordercenter.*;
import com.alibaba.citrus.cr.common.lock.SaleRedisLock;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.StopWatchUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.TrimUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.function.asynctask.AsyncTaskCreateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.AbstractOrderParamsCheckService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.*;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.model.enums.MessageTaskTypeEnum;
import com.epoch.app.mnordercenter.exchangeorderbiz.service.ExchangeOrderBizService;
import com.epoch.app.mnordercenter.model.dto.*;
import com.epoch.app.mnordercenter.orderbaserequest.*;
import com.google.common.collect.Lists;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.alibaba.citrus.cr.mn.order.center.common.constants.RedisLockConstants.*;

/**
 * @author dongju
 * @ClassName ExchangeOrderAtomServiceImpl
 * @description: 换货订单商业服务
 * @date 2023/05/21
 * @version: 1.0
 **/
@Primary
@Component
public class ExchangeOrderBizServiceImpl implements ExchangeOrderBizService {
    private static final Log log = Log.getLogger(ExchangeOrderBizServiceImpl.class);

    @Resource
    private AsyncTaskCreateService asyncTaskCreateService;
    @Resource(name = "exchangeOrderBizCloseService")
    private OrderBizCloseService exchangeOrderBizCloseService;
    @Resource(name = "exchangeOrderBizSubmitService")
    private OrderBizSubmitService exchangeOrderBizSubmitService;
    @Resource
    private SendMsgService sendMsgService;
    @Resource(name = "exchangeOrderBizCreateParamsCheck")
    private AbstractOrderParamsCheckService exchangeOrderBizCreateParamsCheck;
    @Resource(name = "exchangeOrderBizCreateService")
    private OrderBizCreateService<ExchangeOrderBizBatchCreateRequest, ExchangeOrderAtomBatchCreateRequest, OrderAtomCreateResponse> exchangeOrderBizCreateService;
    @Resource(name = "exchangeOrderBizUpdateService")
    private OrderBizUpdateService<OrderBizUpdateRequest, OrderAtomUpdateRequest, OrderAtomUpdateResponse> exchangeOrderBizUpdateService;

    @Override
    @FacadeInvoker(value = "换货订单创建失败", errorCode = "OC-03-001-01-16-007")
    public Result<OrderAtomCreateResponse> create(ExchangeOrderBizCreateRequest request) {
        AssertUtils.isTrue(StringUtils.isBlank(request.getReqNo()), "OC-01-001-01-15-001", "请求编码");

        log.info("ExchangeOrderBizServiceImpl#create request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_BIZ_PREFIX + request.getReqNo();
        log.info("ExchangeOrderBizServiceImpl#create lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderBizServiceImpl#create 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            // 移除入参里的前后空格
            StopWatchUtils.start("订单中心商业创建", "removeSpace");
            TrimUtils.removeSpace(request);
            StopWatchUtils.stop();

            StopWatchUtils.start("订单中心商业创建", "paramsInvalidCheck");
            AssertUtils.lengthCheck(request.getReqNo(), 128, true, "OC-01-001-01-15-004", "请求编码");

            if (StringUtils.isBlank(request.getFulfillmentTypeCode())) {
                request.setFulfillmentTypeCode(FulfillmentTypeEnum.CENTRAL_DELIVERY.getCode());
            }
            if (StringUtils.isBlank(request.getFulfillmentPriority())) {
                request.setFulfillmentPriority(FulfillmentPriorityEnum.NORMAL.getCode());
            }
            if (StringUtils.isBlank(request.getAutoFulfillment())) {
                request.setAutoFulfillment(Boolean.TRUE.toString());
            }
            if (StringUtils.isBlank(request.getOrderChannelCode())) {
                request.setOrderChannelCode(OrderChannelEnum.COMPANY.getCode());
            }
            if (Objects.isNull(request.getIsSubmit())) {
                request.setIsSubmit(Boolean.TRUE);
            }
            if (Objects.isNull(request.getCheckStock())) {
                request.setCheckStock(Boolean.TRUE);
            }

            // 设置默认值
            request.setCheckCredit(Boolean.FALSE);
            request.setCheckCreditB(Boolean.FALSE);
            request.setOrderCategoryCode(OrderCategoryEnum.COMPANY.getCode());

            exchangeOrderBizCreateParamsCheck.paramsInvalidCheck(Lists.newArrayList(request), new ArrayList());
            StopWatchUtils.stop();

            // 组装同步创建入参
            ExchangeOrderBizBatchCreateRequest createRequest = new ExchangeOrderBizBatchCreateRequest();
            createRequest.setReqNo(request.getReqNo());
            createRequest.setBusinessType(request.getBusinessType());
            createRequest.setBusinessUnitCode(request.getBusinessUnitCode());
            createRequest.setFromSys(request.getFromSys());
            createRequest.setOrderList(Lists.newArrayList(request));
            List<OrderAtomCreateResponse> createResponses = exchangeOrderBizCreateService.batchCreate(createRequest);
            log.info("ExchangeOrderBizServiceImpl#create createResponses={}", createResponses);

            if (CollectionUtils.isEmpty(createResponses)) {
                return Result.fail(null, "OC-03-001-01-16-007", "换货订单创建失败");
            }
            OrderAtomCreateResponse orderAtomCreateResponse = createResponses.get(0);
            if (StringUtils.isNotBlank(orderAtomCreateResponse.getErrorCode())) {
                return Result.fail(orderAtomCreateResponse, orderAtomCreateResponse.getErrorCode(), orderAtomCreateResponse.getMessage());
            }
            return Result.success(orderAtomCreateResponse, "", "");
        } catch (Exception e) {
            log.error("ExchangeOrderBizServiceImpl#create error", e);
            throw e;
        } finally {
            StopWatchUtils.print("ExchangeOrderBizServiceImpl#create");
        }
    }

    @Override
    @FacadeInvoker(value = "换货订单批量创建失败", errorCode = "OC-03-001-01-16-006")
    public Result<SalesOrderBizCreateResponse> batchCreate(ExchangeOrderBizBatchCreateRequest request) {
        AssertUtils.isTrue(StringUtils.isBlank(request.getReqNo()), "OC-01-001-01-15-001", "请求编码");

        log.info("ExchangeOrderBizServiceImpl#batchCreate request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_BIZ_PREFIX + request.getReqNo();
        log.info("ExchangeOrderBizServiceImpl#batchCreate lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderBizServiceImpl#batchCreate 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            // 移除入参里的前后空格
            StopWatchUtils.start("订单中心商业创建", "removeSpace");
            TrimUtils.removeSpace(request);
            StopWatchUtils.stop();

            StopWatchUtils.start("订单中心商业创建", "paramsInvalidCheck");
            List<ExchangeOrderBizCreateRequest> orderList = request.getOrderList();
            AssertUtils.lengthCheck(request.getReqNo(), 128, true, "OC-01-001-01-15-004", "请求编码");
            AssertUtils.isTrue(CollectionUtils.isEmpty(orderList), "OC-01-001-01-15-001", "单据列表");

            orderList.forEach(order -> {
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    order.setFromSys(request.getFromSys());
                }
                if (StringUtils.isNotBlank(request.getBusinessType())) {
                    order.setBusinessType(request.getBusinessType());
                }
                if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                    order.setBusinessUnitCode(request.getBusinessUnitCode());
                }

                if (StringUtils.isBlank(order.getFulfillmentTypeCode())) {
                    order.setFulfillmentTypeCode(FulfillmentTypeEnum.CENTRAL_DELIVERY.getCode());
                }
                if (StringUtils.isBlank(order.getFulfillmentPriority())) {
                    order.setFulfillmentPriority(FulfillmentPriorityEnum.NORMAL.getCode());
                }
                if (StringUtils.isBlank(order.getAutoFulfillment())) {
                    order.setAutoFulfillment(Boolean.TRUE.toString());
                }
                if (StringUtils.isBlank(order.getOrderChannelCode())) {
                    order.setOrderChannelCode(OrderChannelEnum.COMPANY.getCode());
                }
                if (Objects.isNull(order.getIsSubmit())) {
                    order.setIsSubmit(Boolean.TRUE);
                }
                if (Objects.isNull(order.getCheckStock())) {
                    order.setCheckStock(Boolean.TRUE);
                }

                // 设置默认值
                order.setCheckCredit(Boolean.FALSE);
                order.setCheckCreditB(Boolean.FALSE);
                order.setOrderCategoryCode(OrderCategoryEnum.COMPANY.getCode());
            });

            exchangeOrderBizCreateParamsCheck.paramsInvalidCheck(orderList, new ArrayList());
            StopWatchUtils.stop();

            StopWatchUtils.start("订单中心商业创建", "createAsyncTask");
            String batchTaskId = asyncTaskCreateService.createAsyncTask(request.getFromSys() + "#" + request.getReqNo(),
                    request.getFromSys(), JSON.toJSONString(request), MessageTaskTypeEnum.OC_EXCHANGE_ORDER_BATCH_CREATE);
            StopWatchUtils.stop();

            SalesOrderBizCreateResponse salesOrderBizCreateResponse = new SalesOrderBizCreateResponse();
            salesOrderBizCreateResponse.setBatchTaskId(batchTaskId);
            return Result.success(salesOrderBizCreateResponse, "", "");

        } catch (Exception e) {
            log.error("ExchangeOrderBizServiceImpl#batchCreate error", e);
            throw e;
        } finally {
            StopWatchUtils.print("ExchangeOrderBizServiceImpl#batchCreate");
        }
    }

    @Override
    @FacadeInvoker(value = "换货订单批量提交失败", errorCode = "OC-03-001-01-16-016")
    public Result<List<OrderAtomSubmitResponse>> batchSubmit(OrderBizBatchSubmitRequest request) {
        log.info("ExchangeOrderBizServiceImpl#batchSubmit request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_BIZ_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ExchangeOrderBizServiceImpl#batchSubmit lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderBizServiceImpl#batchSubmit 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            for (OrderAtomSubmitRequest salesOrder : request.getOrderList()) {
                if (Objects.isNull(salesOrder.getCheckStock())) {
                    salesOrder.setCheckStock(Boolean.TRUE);
                }
                salesOrder.setCheckCredit(Boolean.FALSE);
                salesOrder.setCheckCreditB(Boolean.FALSE);
            }
            request.setOrderCategoryCode(OrderCategoryEnum.COMPANY.getCode());

            List<OrderAtomSubmitResponse> resp = exchangeOrderBizSubmitService.batchSubmit(request);
            if (CollectionUtils.isNotEmpty(resp)) {
                // 发送消息通知来源系统
                List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
                for (OrderAtomSubmitResponse submitResponse : resp) {
                    pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                            .salesOrderNo(submitResponse.getSalesOrderNo())
                            .orderStatus(SalesOrderPushStatusEnum.FAIL_UPDATE.getOrderStatusCode())
                            .message(submitResponse.getMessage())
                            .build());
                }
                // 发送kafka消息通知应用端处理结果
//                sendMsgService.sendMsgToNYK(pushOrderInfoList);
                CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
                commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.EXCHANGE_ORDER_UPDATE.getValue());
                commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.EXCHANGE_ORDER_UPDATE.getLabel());
                commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
                commonAsyncMessageResponse.setFromSys(request.getFromSys());
                commonAsyncMessageResponse.setBusinessUnitCode(request.getBusinessUnitCode());
                commonAsyncMessageResponse.setData(pushOrderInfoList);
                sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
                log.info("ExchangeOrderBizServiceImpl#batchSubmit sendMsgToSendKafka message={}", commonAsyncMessageResponse);
            }
            return Result.success(resp, "", "");

        } catch (Exception e) {
            log.error("ExchangeOrderBizServiceImpl#batchSubmit error", e);
            throw e;
        } finally {
            StopWatchUtils.print("ExchangeOrderBizServiceImpl#batchSubmit");
        }
    }

    @Override
    @FacadeInvoker(value = "换货订单批量关闭", errorCode = "OC-03-001-01-16-013")
    public Result<List<OrderAtomCloseResponse>> batchClose(OrderBizBatchCloseRequest request) {
        log.info("ExchangeOrderBizServiceImpl#batchClose request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_BIZ_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ExchangeOrderBizServiceImpl#batchClose lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderBizServiceImpl#batchClose 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            return exchangeOrderBizCloseService.batchClose(request);
        } catch (Exception e) {
            log.error("ExchangeOrderBizServiceImpl#batchClose error", e);
            throw e;
        } finally {
            StopWatchUtils.print("ExchangeOrderBizServiceImpl#batchClose");
        }
    }

    @Override
    @FacadeInvoker(value = "换货订单更新失败", errorCode = "OC-03-001-01-16-014")
    public Result<OrderAtomUpdateResponse> update(OrderBizUpdateRequest request) {
        log.info("ExchangeOrderBizServiceImpl#update request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_BIZ_PREFIX + request.getSalesOrderNo();
        log.info("ExchangeOrderBizServiceImpl#update lockKey={}", lockKey);
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderBizServiceImpl#update 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            if (Objects.isNull(request.getCheckStock())) {
                request.setCheckStock(Boolean.TRUE);
            }

            // 设置默认值
            request.setCheckCredit(Boolean.FALSE);
            request.setCheckCreditB(Boolean.FALSE);
            request.setOrderCategoryCode(OrderCategoryEnum.COMPANY.getCode());

            OrderAtomUpdateResponse response = exchangeOrderBizUpdateService.update(request);
            if (StringUtils.isNotBlank(response.getErrorCode())) {
                return Result.fail(response, "", "");
            }
            return Result.success(response, "", "");

        } catch (Exception e) {
            log.error("ExchangeOrderBizServiceImpl#update error", e);
            throw e;
        } finally {
            StopWatchUtils.print("ExchangeOrderBizServiceImpl#update");
        }
    }
}
